package com.framework.persist;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.naming.NamingException;
import javax.sql.DataSource;

import com.framework.comm.Config;
import com.framework.exception.FetchConnectionException;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DataSourceManager {
	
	private static final String LOCAL_SUPORT = "connect";
	
	private static final String JNDI_SUPPORT = "jndi";
	
	private static final String LOCAL_POOL_SUPPORT = "pool";
	
	private static final String C3P0 = "c3p0";
	
	private static DataSourceManager manager = new DataSourceManager();

	private DataSource dataSource = null;

	private DataSourceManager() {

	}
	
	public synchronized void loadDataSource() throws  FetchConnectionException{
		String support = Config.support;
		if(support == null){
			throw new FetchConnectionException("Connectin.support is not Config");
		}
		if(support.equals(LOCAL_SUPORT)){
			String driverClassName = Config.driver;
			String url = Config.url ;
			String username = Config.username;
			String password = Config.passwd ;
			dataSource = new DrvMgrDataSource(driverClassName, url, username, password);
			Properties props =new Properties();
			props.put("remarksReporting","true");
			((DrvMgrDataSource)dataSource).setConnectionProperties(props);

		}else if(support.equals(JNDI_SUPPORT)){
			String jndiName = Config.dataSource;
			if(jndiName == null)
				throw new FetchConnectionException("connection.datasource have not defined");
			try {
				dataSource = JndiDataSourceFactory.getDataSource(jndiName);
			} catch (NamingException e) {
				e.printStackTrace();
				throw new FetchConnectionException("Jndi Look up Error", e);
			}
		} else if(support.equals(LOCAL_POOL_SUPPORT)){
			
		} else if(support.equals(C3P0)){
			dataSource = new ComboPooledDataSource();
			String driverClassName = Config.driver;
			String url = Config.url ;
			String username = Config.username;
			String password = Config.passwd ;
			Properties props =new Properties();
			props.put("remarksReporting","true");
			((ComboPooledDataSource)dataSource).setProperties(props);
			((ComboPooledDataSource)dataSource).setUser(username);
			((ComboPooledDataSource)dataSource).setPassword(password);
			try {
				((ComboPooledDataSource)dataSource).setDriverClass(driverClassName);
			} catch (PropertyVetoException e) {
				throw new FetchConnectionException("connection.datasource have not defined");
			}
			((ComboPooledDataSource)dataSource).setJdbcUrl(url);
			
			if(!"".equals(Config.acquireIncrement)){
				((ComboPooledDataSource)dataSource).setAcquireIncrement(Short.parseShort(Config.acquireIncrement));
			}
			if(!"".equals(Config.minPoolSize )){
				((ComboPooledDataSource)dataSource).setMinPoolSize(Integer.parseInt(Config.minPoolSize));
			}
			if(!"".equals(Config.maxPoolSize)){
				((ComboPooledDataSource)dataSource).setMaxPoolSize(Integer.parseInt(Config.maxPoolSize));
			}
			if(!"".equals(Config.initialPoolSize)){
				((ComboPooledDataSource)dataSource).setInitialPoolSize(Integer.parseInt(Config.initialPoolSize));
			}
			if(!"".equals(Config.maxIdleTime)){
				((ComboPooledDataSource)dataSource).setMaxIdleTime(Integer.parseInt(Config.maxIdleTime));
			}
		}else {
			throw new FetchConnectionException("UnSupport Connection DataSource");
		}
	}

	public static DataSourceManager getInstance() {
		return manager;
	}

	public Connection getConnection() throws FetchConnectionException,
			SQLException {
		if (this.dataSource == null)
			throw new FetchConnectionException("Fetch Connection Exception.");
		return dataSource.getConnection();
	}

	public DataSource getDataSource() {
		return dataSource;
	}
}
